package com.minimalist.common.entity.basic.po;

import com.mybatisflex.annotation.Table;
import com.minimalist.common.config.mybatis.InsertFullColumnHandler;
import com.minimalist.common.config.mybatis.UpdateFullColumnHandler;
import com.minimalist.common.config.mybatis.bo.BaseEntity;

import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 通知公告表实体类
 * <p>
 * 用于管理系统通知公告信息，包括公告的基本信息、
 * 发布状态、置顶设置、外链配置等功能
 *
 * @author 小太阳
 * @since 2024-10-18
 */
@Table(value = "m_notice", onInsert = InsertFullColumnHandler.class, onUpdate = UpdateFullColumnHandler.class)
public class MNotice extends BaseEntity implements Serializable {
    
    @Serial
    private static final long serialVersionUID = 1L;

    // ========== 基本信息字段 ==========
    
    /**
     * 公告ID
     */
    private Long noticeId;

    /**
     * 公告标题
     */
    private String noticeTitle;

    /**
     * 公告类型（1公告）
     */
    private Integer noticeType;

    /**
     * 公告内容
     */
    private String noticeContent;

    /**
     * 封面图文件ID，多个使用 , 分割
     */
    private String noticePicFileId;

    // ========== 状态和配置字段 ==========
    
    /**
     * 是否置顶 0否 1是
     */
    private Boolean noticeTop;

    /**
     * 排序
     */
    private Integer noticeSort;

    /**
     * 状态 0禁用 1正常
     */
    private Integer status;

    /**
     * 是否外链 0否 1是
     */
    private Boolean noticeOutChain;

    /**
     * 外部跳转链接
     */
    private String noticeLink;

    // ========== 时间字段 ==========
    
    /**
     * 延时发布的时间
     */
    private LocalDateTime noticeTimeInterval;

    /**
     * 发布时间
     */
    private LocalDateTime publishTime;

    // ========== 发布相关字段 ==========
    
    /**
     * 发布部门
     */
    private Long publishDeptId;

    /**
     * 发布人
     */
    private Long publishAuthorId;

    /**
     * 租户ID
     */
    private Long tenantId;

    // ========== 构造函数 ==========
    
    /**
     * 默认构造函数
     */
    public MNotice() {
    }

    /**
     * 全参数构造函数
     *
     * @param noticeId            公告ID
     * @param noticeTitle         公告标题
     * @param noticeType          公告类型
     * @param noticeContent       公告内容
     * @param noticePicFileId     封面图文件ID
     * @param noticeTop           是否置顶
     * @param noticeSort          排序
     * @param status              状态
     * @param noticeOutChain      是否外链
     * @param noticeLink          外部跳转链接
     * @param noticeTimeInterval  延时发布时间
     * @param publishTime         发布时间
     * @param publishDeptId       发布部门
     * @param publishAuthorId     发布人
     * @param tenantId            租户ID
     */
    public MNotice(Long noticeId, String noticeTitle, Integer noticeType, String noticeContent,
                   String noticePicFileId, Boolean noticeTop, Integer noticeSort, Integer status,
                   Boolean noticeOutChain, String noticeLink, LocalDateTime noticeTimeInterval,
                   LocalDateTime publishTime, Long publishDeptId, Long publishAuthorId, Long tenantId) {
        this.noticeId = noticeId;
        this.noticeTitle = noticeTitle;
        this.noticeType = noticeType;
        this.noticeContent = noticeContent;
        this.noticePicFileId = noticePicFileId;
        this.noticeTop = noticeTop;
        this.noticeSort = noticeSort;
        this.status = status;
        this.noticeOutChain = noticeOutChain;
        this.noticeLink = noticeLink;
        this.noticeTimeInterval = noticeTimeInterval;
        this.publishTime = publishTime;
        this.publishDeptId = publishDeptId;
        this.publishAuthorId = publishAuthorId;
        this.tenantId = tenantId;
    }

    /**
     * 基本信息构造函数
     *
     * @param noticeTitle   公告标题
     * @param noticeType    公告类型
     * @param noticeContent 公告内容
     */
    public MNotice(String noticeTitle, Integer noticeType, String noticeContent) {
        this.noticeTitle = noticeTitle;
        this.noticeType = noticeType;
        this.noticeContent = noticeContent;
        this.noticeTop = false; // 默认不置顶
        this.status = 1; // 默认正常状态
        this.noticeOutChain = false; // 默认非外链
    }

    // ========== Getter 和 Setter 方法 ==========
    
    public Long getNoticeId() {
        return noticeId;
    }

    public void setNoticeId(Long noticeId) {
        this.noticeId = noticeId;
    }

    public String getNoticeTitle() {
        return noticeTitle;
    }

    public void setNoticeTitle(String noticeTitle) {
        this.noticeTitle = noticeTitle;
    }

    public Integer getNoticeType() {
        return noticeType;
    }

    public void setNoticeType(Integer noticeType) {
        this.noticeType = noticeType;
    }

    public String getNoticeContent() {
        return noticeContent;
    }

    public void setNoticeContent(String noticeContent) {
        this.noticeContent = noticeContent;
    }

    public String getNoticePicFileId() {
        return noticePicFileId;
    }

    public void setNoticePicFileId(String noticePicFileId) {
        this.noticePicFileId = noticePicFileId;
    }

    public Boolean getNoticeTop() {
        return noticeTop;
    }

    public void setNoticeTop(Boolean noticeTop) {
        this.noticeTop = noticeTop;
    }

    public Integer getNoticeSort() {
        return noticeSort;
    }

    public void setNoticeSort(Integer noticeSort) {
        this.noticeSort = noticeSort;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Boolean getNoticeOutChain() {
        return noticeOutChain;
    }

    public void setNoticeOutChain(Boolean noticeOutChain) {
        this.noticeOutChain = noticeOutChain;
    }

    public String getNoticeLink() {
        return noticeLink;
    }

    public void setNoticeLink(String noticeLink) {
        this.noticeLink = noticeLink;
    }

    public LocalDateTime getNoticeTimeInterval() {
        return noticeTimeInterval;
    }

    public void setNoticeTimeInterval(LocalDateTime noticeTimeInterval) {
        this.noticeTimeInterval = noticeTimeInterval;
    }

    public LocalDateTime getPublishTime() {
        return publishTime;
    }

    public void setPublishTime(LocalDateTime publishTime) {
        this.publishTime = publishTime;
    }

    public Long getPublishDeptId() {
        return publishDeptId;
    }

    public void setPublishDeptId(Long publishDeptId) {
        this.publishDeptId = publishDeptId;
    }

    public Long getPublishAuthorId() {
        return publishAuthorId;
    }

    public void setPublishAuthorId(Long publishAuthorId) {
        this.publishAuthorId = publishAuthorId;
    }

    public Long getTenantId() {
        return tenantId;
    }

    public void setTenantId(Long tenantId) {
        this.tenantId = tenantId;
    }

    // ========== Object 方法重写 ==========
    
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        if (!super.equals(o)) {
            return false;
        }
        
        MNotice mNotice = (MNotice) o;
        
        return Objects.equals(noticeId, mNotice.noticeId) &&
               Objects.equals(noticeTitle, mNotice.noticeTitle) &&
               Objects.equals(noticeType, mNotice.noticeType) &&
               Objects.equals(noticeContent, mNotice.noticeContent) &&
               Objects.equals(noticePicFileId, mNotice.noticePicFileId) &&
               Objects.equals(noticeTop, mNotice.noticeTop) &&
               Objects.equals(noticeSort, mNotice.noticeSort) &&
               Objects.equals(status, mNotice.status) &&
               Objects.equals(noticeOutChain, mNotice.noticeOutChain) &&
               Objects.equals(noticeLink, mNotice.noticeLink) &&
               Objects.equals(noticeTimeInterval, mNotice.noticeTimeInterval) &&
               Objects.equals(publishTime, mNotice.publishTime) &&
               Objects.equals(publishDeptId, mNotice.publishDeptId) &&
               Objects.equals(publishAuthorId, mNotice.publishAuthorId) &&
               Objects.equals(tenantId, mNotice.tenantId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), noticeId, noticeTitle, noticeType, noticeContent,
                           noticePicFileId, noticeTop, noticeSort, status, noticeOutChain,
                           noticeLink, noticeTimeInterval, publishTime, publishDeptId,
                           publishAuthorId, tenantId);
    }

    @Override
    public String toString() {
        return "MNotice{" +
               "noticeId=" + noticeId +
               ", noticeTitle='" + noticeTitle + '\'' +
               ", noticeType=" + noticeType +
               ", noticeContent='" + noticeContent + '\'' +
               ", noticePicFileId='" + noticePicFileId + '\'' +
               ", noticeTop=" + noticeTop +
               ", noticeSort=" + noticeSort +
               ", status=" + status +
               ", noticeOutChain=" + noticeOutChain +
               ", noticeLink='" + noticeLink + '\'' +
               ", noticeTimeInterval=" + noticeTimeInterval +
               ", publishTime=" + publishTime +
               ", publishDeptId=" + publishDeptId +
               ", publishAuthorId=" + publishAuthorId +
               ", tenantId=" + tenantId +
               '}';
    }

    // ========== Builder 模式 ==========
    
    /**
     * 创建Builder实例
     *
     * @return MNoticeBuilder实例
     */
    public static MNoticeBuilder builder() {
        return new MNoticeBuilder();
    }

    /**
     * MNotice建造者类
     */
    public static class MNoticeBuilder {
        private Long noticeId;
        private String noticeTitle;
        private Integer noticeType;
        private String noticeContent;
        private String noticePicFileId;
        private Boolean noticeTop;
        private Integer noticeSort;
        private Integer status;
        private Boolean noticeOutChain;
        private String noticeLink;
        private LocalDateTime noticeTimeInterval;
        private LocalDateTime publishTime;
        private Long publishDeptId;
        private Long publishAuthorId;
        private Long tenantId;

        public MNoticeBuilder noticeId(Long noticeId) {
            this.noticeId = noticeId;
            return this;
        }

        public MNoticeBuilder noticeTitle(String noticeTitle) {
            this.noticeTitle = noticeTitle;
            return this;
        }

        public MNoticeBuilder noticeType(Integer noticeType) {
            this.noticeType = noticeType;
            return this;
        }

        public MNoticeBuilder noticeContent(String noticeContent) {
            this.noticeContent = noticeContent;
            return this;
        }

        public MNoticeBuilder noticePicFileId(String noticePicFileId) {
            this.noticePicFileId = noticePicFileId;
            return this;
        }

        public MNoticeBuilder noticeTop(Boolean noticeTop) {
            this.noticeTop = noticeTop;
            return this;
        }

        public MNoticeBuilder noticeSort(Integer noticeSort) {
            this.noticeSort = noticeSort;
            return this;
        }

        public MNoticeBuilder status(Integer status) {
            this.status = status;
            return this;
        }

        public MNoticeBuilder noticeOutChain(Boolean noticeOutChain) {
            this.noticeOutChain = noticeOutChain;
            return this;
        }

        public MNoticeBuilder noticeLink(String noticeLink) {
            this.noticeLink = noticeLink;
            return this;
        }

        public MNoticeBuilder noticeTimeInterval(LocalDateTime noticeTimeInterval) {
            this.noticeTimeInterval = noticeTimeInterval;
            return this;
        }

        public MNoticeBuilder publishTime(LocalDateTime publishTime) {
            this.publishTime = publishTime;
            return this;
        }

        public MNoticeBuilder publishDeptId(Long publishDeptId) {
            this.publishDeptId = publishDeptId;
            return this;
        }

        public MNoticeBuilder publishAuthorId(Long publishAuthorId) {
            this.publishAuthorId = publishAuthorId;
            return this;
        }

        public MNoticeBuilder tenantId(Long tenantId) {
            this.tenantId = tenantId;
            return this;
        }

        public MNotice build() {
            return new MNotice(noticeId, noticeTitle, noticeType, noticeContent, noticePicFileId,
                              noticeTop, noticeSort, status, noticeOutChain, noticeLink,
                              noticeTimeInterval, publishTime, publishDeptId, publishAuthorId, tenantId);
        }
    }

    // ========== 便利方法 ==========
    
    /**
     * 检查公告是否置顶
     *
     * @return true如果置顶，否则false
     */
    public boolean isTop() {
        return Boolean.TRUE.equals(this.noticeTop);
    }

    /**
     * 检查公告是否启用
     *
     * @return true如果启用，否则false
     */
    public boolean isEnabled() {
        return Integer.valueOf(1).equals(this.status);
    }

    /**
     * 检查公告是否禁用
     *
     * @return true如果禁用，否则false
     */
    public boolean isDisabled() {
        return Integer.valueOf(0).equals(this.status);
    }

    /**
     * 检查是否为外链公告
     *
     * @return true如果是外链，否则false
     */
    public boolean isOutChain() {
        return Boolean.TRUE.equals(this.noticeOutChain);
    }

    /**
     * 设置公告为置顶
     */
    public void setTop() {
        this.noticeTop = true;
    }

    /**
     * 取消公告置顶
     */
    public void cancelTop() {
        this.noticeTop = false;
    }

    /**
     * 启用公告
     */
    public void enable() {
        this.status = 1;
    }

    /**
     * 禁用公告
     */
    public void disable() {
        this.status = 0;
    }

    /**
     * 检查是否有封面图
     *
     * @return true如果有封面图，否则false
     */
    public boolean hasPicture() {
        return noticePicFileId != null && !noticePicFileId.trim().isEmpty();
    }

    /**
     * 检查是否已发布
     *
     * @return true如果已发布，否则false
     */
    public boolean isPublished() {
        return publishTime != null;
    }

    /**
     * 检查是否为延时发布
     *
     * @return true如果是延时发布，否则false
     */
    public boolean isDelayedPublish() {
        return noticeTimeInterval != null && noticeTimeInterval.isAfter(LocalDateTime.now());
    }
}
